import json
import abc
import time
import base64
import hmac
import requests
from django.shortcuts import redirect
from .utils import make_jwt
from .models import User
import urllib
from hashlib import sha256
from mydjango import settings
from .models import Log


# 钉钉url
class DingdingUrl:

    def __repr__(self):
        # appid = 'dingoadguqlojm67rfpc4s'
        appid = 'dingoa8h6btt33lbxtr9c4'
        redirect_uri = settings.Django_URL + 'myapp/teipartite_back/'

        return 'https://oapi.dingtalk.com/connect/qrconnect?appid='+appid+'&response_type=code&scope=snsapi_login&state=STATE&redirect_uri='+redirect_uri


# 钉钉回调
class DingdingBack:
    def __init__(self, code):
        self.code = code

    def __repr__(self):
        t = time.time()
        # 时间戳
        timestamp = str((int(round(t * 1000))))
        # appSecret = '4DEbQ1QO8FPZD4-O0qft1AjmakQJB3j6tUqwG1LIbhhMQR5CDnw8zwOWS8UUhAOL'
        appSecret = 'dPXfBOgE1eL3v5KWLJdoB-E2KutF6X26TXh5-tLRmA4ybjw1G4cQLEKgtRpkMVAS'
        # 构造签名
        signature = base64.b64encode(
            hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod=sha256).digest())
        # 请求接口，换取钉钉用户名
        payload = {'tmp_auth_code': self.code}
        headers = {'Content-Type': 'application/json'}
        # dingoadguqlojm67rfpc4s
        res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=' + urllib.parse.quote(
            signature.decode("utf-8")) + "&timestamp=" + timestamp + "&accessKey=dingoa8h6btt33lbxtr9c4",
                            data=json.dumps(payload), headers=headers)

        res_dict = json.loads(res.text)
        print("钉钉信息",res_dict)
        # 判断数据库中有没有这个用户数据，有就直接返回信息，没有创建一个新用户返回信息
        user_obj = User.objects.filter(username=res_dict["user_info"]['openid'])
        if user_obj:
            user_obj = user_obj.first()
            uid = str(user_obj.id)
            username = user_obj.nickname
            token = make_jwt({'uid': user_obj.id})
            log_obj = Log(uid=uid, log='用户%s进行登录'%username)
            log_obj.save()
            return settings.Vue_URL + 'dingding_back?uid=' + uid + '&username=' + username + '&token=' + token

        else:
            user_obj = User(username=res_dict["user_info"]['openid'], nickname=res_dict["user_info"]['nick'])
            user_obj.save()
            user = User.objects.get(username=res_dict["user_info"]['openid'])
            uid = str(user.id)
            username = user.nickname
            token = make_jwt({'uid': uid})
            log_obj = Log(uid=uid, log='用户%s进行登录'%username)
            log_obj.save()
            return settings.Vue_URL + 'dingding_back?uid=' + uid + '&username=' + username + '&token=' + token


# gitee的url
class GiteeUrl:

    def __repr__(self):
        clientId = 'c18af9db95b75fca8ea22d1c926e7b505b75dcd6343458cce1458ea24db5838f'
        redirect_uri = settings.Django_URL + 'myapp/teipartite_back/'
        return 'https://gitee.com/oauth/authorize?client_id='+clientId+'&redirect_uri='+redirect_uri+'&response_type=code'


class GiteeBack:

    def __init__(self, code):
        self.code = code

    def __repr__(self):
        # 自己的client_id
        client_id = 'c18af9db95b75fca8ea22d1c926e7b505b75dcd6343458cce1458ea24db5838f'
        # client_secret
        client_secret = '238190409b0b27c818ad5068e47ac38d7433185791337923950243c72973d4a8'
        # 应用回调地址
        redirect_uri = settings.Django_URL + 'myapp/teipartite_back/'
        # 拼接请求地址
        res = requests.post(
            'https://gitee.com/oauth/token?grant_type=authorization_code&code=' + self.code + '&client_id=' + client_id + '&redirect_uri=' + redirect_uri + '&client_secret=' + client_secret)
        # 拿到请求后获取的信息
        res = json.loads(res.text)

        # 获取access_token
        token = res['access_token']
        # 将access_token参数带上请求此地址，可以获取到用户信息
        message = requests.get('https://gitee.com/api/v5/user?access_token=' + token)
        mess = json.loads(message.text)
        username = mess['id']
        nickname = mess['name']

        # 判断数据库中有没有这个用户数据，有就直接返回信息，没有创建一个新用户返回信息
        user_obj = User.objects.filter(username=username)
        if user_obj:
            user_obj = user_obj.first()
            uid = str(user_obj.id)
            username = nickname
            token = make_jwt({'uid': uid})
            log_obj = Log(uid=uid, log='用户%s进行登录'%username)
            log_obj.save()
            return settings.Vue_URL + 'gitee_back?uid=' + uid + '&username=' + username + '&token=' + token
        else:
            user = User(username=username, nickname=nickname)
            user.save()
            # user_obj = User.objects.get(username=username)
            uid = str(user.id)
            username = user.nickname
            token = make_jwt({'uid': uid})
            log_obj = Log(uid=uid, log='用户%s进行登录'%username)
            log_obj.save()
            return settings.Vue_URL + 'gitee_back?uid=' + uid + '&username=' + username + '&token=' + token


# 抽象工厂
class AbstractFactory:
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def tripartite_url(self):
        pass

    @abc.abstractmethod
    def tripartite_back(code):
        pass


# 钉钉工厂
class DingdingFactory(AbstractFactory):

    def tripartite_url(self):
        return DingdingUrl()

    def tripartite_back(code):
        return DingdingBack(code)


# gitee工厂
class GiteeFactory(AbstractFactory):

    def tripartite_url(self):
        return GiteeUrl()

    def tripartite_back(code):
        return GiteeBack(code)



